// Header Protection
#ifndef _SYSTEM_H_
#define _SYSTEM_H_

// Namespace
namespace IE
{
	/////////////////////////////////////////////////////////////////////////////////
	// A base class from which to derive all scene systems. Each system is run on a 
	//     thread, and acts on 'Nodes', which contain all data about an object which 
	//     is relevant to the system.
	class ABCSystem
	{
	protected:  // methods
		ABCSystem()
			: m_DataMutex(), m_hThread(NULL), m_bRunning(FALSE), m_uFrameRate(0)
		{ }
		virtual ~ABCSystem() = 0 { }

		// Start running the system thread at the given FPS. This method calls 
		//     ThreadBegin, and does not return until it is complete.
		// _uFrameRate: uint_t - the number of frames per second, 0 for as fast as 
		//     possible.
		void StartThread( uint_t _uFrameRate );

		// Stop running the system thread. This method calls ThreadEnd, and does not 
		//     return until it is complete.
		void StopThread();

		// This pure virtual method is called just after the thread is created.
		//     StartThread does not return until this method does.
		virtual void ThreadBegin() = 0;

		// This pure virtual method is called at the interval given 
		//     by the current frame rate.
		// _fTime: float_t - the time, in seconds, that has elapsed since 
		//     the last tick
		virtual void ThreadTick( float_t _fTime ) = 0;

		// This pure virtual method is called just before the thread is destroyed.
		//     StopThread does not return until this method does.
		virtual void ThreadEnd() = 0;

	private:    // thread procedure

		// The thread procedure for all systems.
		// _pSystem: void * - A pointer to the system that this procedure is for.
		// return: uint_t - the exit status of the system.
		static uint_t __stdcall ThreadProc( void * _pSystem );

	private:    // thread data
		mutex_t m_DataMutex;
		HANDLE  m_hThread;
		bool_t  m_bRunning;
		int_t   m_uFrameRate;

	private:    // dummy definitions
		ABCSystem( ABCSystem const & );
		ABCSystem &operator =( ABCSystem const & );
	};
}

// Header Protection
#endif // _SYSTEM_H_
